﻿using System;
using System.Collections.Generic;
using UnityEngine;
using FairyGUI;
using taurus.client;

public class ChatMain : MonoBehaviour
{
    GComponent _mainView;
    GList _list;
    GTextInput _input1;
    GComponent _emojiSelectUI1;
    Controller _ctr,_ctr1;
    GTextInput _input_host;
    GTextInput _input_user;
    GTextField _txt_tip;
    TaurusClient _client;
    string _user;

    class CMessage
    {
        public string sender;
        public string senderIcon;
        public string msg;
        public bool fromMe;
    }
    List<CMessage> _messages;
    

    void Awake()
    {
        UIPackage.AddPackage("UI/Chat");

        UIConfig.verticalScrollBar = "ui://Chat/ScrollBar_VT";
        UIConfig.defaultScrollBarDisplay = ScrollBarDisplayType.Auto;

        taurus.client.Logger.loggerPrint = (lev, msg) =>
        {
            switch (lev)
            {
                case LoggerLevel.INFO:
                case LoggerLevel.DEBUG:
                case LoggerLevel.TRACE:
                    UnityEngine.Debug.Log(msg);
                    break;
                case LoggerLevel.WARN:
                    UnityEngine.Debug.LogWarning(msg);
                    break;
                case LoggerLevel.ERROR:
                    UnityEngine.Debug.LogError(msg);
                    break;
            }
        };
    }

    void Start()
    {
        Application.targetFrameRate = 60;
        Stage.inst.onKeyDown.Add(OnKeyDown);

        _messages = new List<CMessage>();

        _mainView = this.GetComponent<UIPanel>().ui;

        _list = _mainView.GetChild("list").asList;
        _list.SetVirtual();
        _list.itemProvider = GetListItemResource;
        _list.itemRenderer = RenderListItem;

        _input1 = _mainView.GetChild("input1").asTextInput;
        _input1.onKeyDown.Add(__inputKeyDown1);

        _mainView.GetChild("btnSend1").onClick.Add(__clickSendBtn1);

        _mainView.GetChild("btnEmoji1").onClick.Add(__clickEmojiBtn1);

        _emojiSelectUI1 = UIPackage.CreateObject("Chat", "EmojiSelectUI").asCom;
        _emojiSelectUI1.fairyBatching = true;
        _emojiSelectUI1.GetChild("list").asList.onClickItem.Add(__clickEmoji1);

        _txt_tip = _mainView.GetChild("txt_tip").asTextField;
        _ctr = _mainView.GetControllerAt(0);

        var _connectView = _mainView.GetChild("connect").asCom;
        _ctr1 = _connectView.GetControllerAt(0);
        _input_host = _connectView.GetChild("input_host").asTextInput;
        _input_user = _connectView.GetChild("input_user").asTextInput;
        var btn_conn = _connectView.GetChild("btn_conn");
        btn_conn.onClick.Add(() =>
        {
            var host = _input_host.text;
            var user = _input_user.text;
            ConnectedServer(host, user);
        });
    }

    void ConnectedServer(string host, string user)
    {
        if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(user))
            return;
        _user = user;
        _ctr1.selectedIndex = 1;
        ITObject validate = TObject.newInstance();
        validate.putString("user", user);

        if (_client != null)
        {
            _client.killConnection();
            _client = null;
        }
        _client = new TaurusClient(host, "chat", ConnectionProtocol.Tcp);
        _client.connect(validate);
        _client.addEventListener(NetClientEvent.Connect, (evt) =>
        {
            SocketCode code = (SocketCode)evt.getParameter("code");
            _ctr1.selectedIndex = 0;
            if (code == SocketCode.Connect)
            {
                _txt_tip.visible = false;
                _ctr.selectedIndex = 1;
            }
            else
            {
                _ctr.selectedIndex = 0;
                _txt_tip.visible = true;
            }
        });
        _client.addEventListener(NetClientEvent.OnEvent, (evt) =>
        {
            var msg = evt.getParameter("msg") as Message;
            if(msg.command == "evt_msg")
            {
                var name = msg.param.getUtfString("name");
                var text = msg.param.getUtfString("msg");
                var head = msg.param.getUtfString("head");
                AddMsg(name, head, text, name == _user);
            }
        });
     }

    void AddMsg(string sender, string senderIcon, string msg, bool fromMe)
    {
        bool isScrollBottom = _list.scrollPane.isBottomMost;

        CMessage newMessage = new CMessage();
        newMessage.sender = sender;
        newMessage.senderIcon = senderIcon;
        newMessage.msg = msg;
        newMessage.fromMe = fromMe;
        _messages.Add(newMessage);

        if (_messages.Count > 100)
            _messages.RemoveRange(0, _messages.Count - 100);

        _list.numItems = _messages.Count;

        if (isScrollBottom)
            _list.scrollPane.ScrollBottom();
    }

    string GetListItemResource(int index)
    {
        CMessage msg = _messages[index];
        if (msg.fromMe)
            return "ui://Chat/chatRight";
        else
            return "ui://Chat/chatLeft";
    }

    void RenderListItem(int index, GObject obj)
    {
        GButton item = (GButton)obj;
        CMessage msg = _messages[index];
        if (!msg.fromMe)
            item.GetChild("name").text = msg.sender;
        item.icon = UIPackage.GetItemURL("Chat", msg.senderIcon);

        //Recaculate the text width
        GRichTextField tf = item.GetChild("msg").asRichTextField;
        tf.text = EmojiParser.inst.Parse(msg.msg);
    }

    void __clickSendBtn1(EventContext context)
    {
        string msg = _input1.text;
        if (msg.Length == 0)
            return;


        ITObject parm = TObject.newInstance();
        parm.putUtfString("msg", msg);
        parm.putUtfString("head", "r0");
        _client.send("chat/msg", parm, null);
        _input1.text = "";
    }

    void __clickEmojiBtn1(EventContext context)
    {
        GRoot.inst.ShowPopup(_emojiSelectUI1, (GObject)context.sender, PopupDirection.Up);
    }

    void __clickEmoji1(EventContext context)
    {
        GButton item = (GButton)context.data;
        _input1.ReplaceSelection("[:" + item.text + "]");
    }

    void __inputKeyDown1(EventContext context)
    {
        if (context.inputEvent.keyCode == KeyCode.Return)
            _mainView.GetChild("btnSend1").onClick.Call();
    }

    void OnKeyDown(EventContext context)
    {
        if (context.inputEvent.keyCode == KeyCode.Escape)
        {
            Application.Quit();
        }
    }

    void Update()
    {
        NetManager.processEvents();
    }

    void OnApplicationQuit()
    {
        NetManager.killAllConnection();
    }
}